package demo;

import java.io.FileDescriptor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.Socket;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import model.PropertyInfo;
import model.User;

import com.mysql.jdbc.Blob;
import com.mysql.jdbc.Connection;

public class JDBCDao {

	private Connection connection;

	private Statement statement;

	private ResultSet resultSet;

	/**
	 * 实际分析flex传递数据的入口
	 * 
	 * @param propertyInfo
	 * @param amf 
	 * @param socket 
	 */
	public void solveInfo(PropertyInfo propertyInfo, Socket socket, AMF3 amf) {
		int code = propertyInfo.getCode();
		PropertyInfo propertyInfoResult = new PropertyInfo();
		propertyInfoResult.setDataFuncName(propertyInfo.getDataFuncName());
		propertyInfoResult.setDataProperties(propertyInfo.getDataProperties());
		if (code == 1) {
			User user = solveUserLogin((User) propertyInfo.getData());
			if(user == null){
				propertyInfoResult.setCode(-1);
			}else{
				propertyInfoResult.setData(user);
			}
			amf.sendAmfData(propertyInfoResult, socket);
		}
	}

	/**
	 * 玩家登陆
	 * 
	 * @param data
	 */
	private User solveUserLogin(User user) {
		String passport = "";
		String password = "";
		User userDB = null;
		if (user != null && (passport = user.getPassport()) != ""
				&& (password = user.getPassword()) != "") {
			String sql = "select * from u_passport u where u.passport = '"
					+ passport + "' and u.password = '" + password + "'";
			userDB = getObjBySql(sql, user.getClass());
		}
		return userDB;
	}

	/**
	 * 根据sql语句和类名查询，获取多条记录，返回list
	 * 
	 * @param <T>
	 * @param sql
	 * @param persistentClass
	 * @return
	 */
	public <T> List<T> getListBySql(String sql, Class<T> persistentClass) {
		List<T> list = new ArrayList<T>();
		T obj;
		try {
			resultSet = this.getStatement().executeQuery(sql);
			while (resultSet.next()) {
				Map<String, Object> map = getMapByResult(resultSet,
						persistentClass);
				obj = setMapToObj(map, persistentClass);
				list.add(obj);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 根据sql语句返回一条记录的对象
	 * 
	 * @param sql
	 * @param persistentClass
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getObjBySql(String sql, Class<T> persistentClass) {
		T obj = null;
		try {
			resultSet = this.getStatement().executeQuery(sql);
			while (resultSet.next()) {
				Map<String, Object> map = getMapByResult(resultSet,
						persistentClass);
				obj = setMapToObj(map, persistentClass);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 根据类的信息，将resultset中的数据转入map中
	 * 
	 * @param resultSet
	 * @param persistentClass
	 * @return
	 * @throws SQLException
	 */
	private Map<String, Object> getMapByResult(ResultSet resultSet,
			Class<?> persistentClass) throws SQLException {
		Field[] fields = persistentClass.getDeclaredFields();
		Map<String, Object> map = new HashMap<String, Object>();
		for (int i = 0; i < fields.length; i++) {
			Field curField = fields[i];
			String fieldName = curField.getName();
			Class<?> fieldType = curField.getType();
			Object value = null;
			if (fieldType == Long.class) {
				value = resultSet.getLong(fieldName);
			}
			if (fieldType == String.class) {
				value = resultSet.getString(fieldName);
			}
			if (fieldType == Date.class) {
				value = resultSet.getDate(fieldName);
			}
			if (fieldType == Integer.class) {
				value = resultSet.getInt(fieldName);
			}
			if (fieldType == BigDecimal.class) {
				value = resultSet.getBigDecimal(fieldName);
			}
			if (fieldType == Boolean.class) {
				value = resultSet.getBoolean(fieldName);
			}
			if (fieldType == java.sql.Blob.class) {
				value = resultSet.getBlob(fieldName);
			}
			if (fieldType == Double.class) {
				value = resultSet.getDouble(fieldName);
			}
			if (fieldType == Float.class) {
				value = resultSet.getFloat(fieldName);
			}
			if (fieldType == Timestamp.class) {
				value = resultSet.getTimestamp(fieldName);
			}
			if (fieldType == Short.class) {
				value = resultSet.getShort(fieldName);
			}
			map.put(fieldName, value);
		}
		return map;
	}

	/**
	 * 通过类名，将map转换成对象
	 * 
	 * @param <T>
	 * @param map
	 * @param persistentClass
	 * @return
	 */
	@SuppressWarnings("unused")
	private <T> T setMapToObj(Map<String, Object> map, Class<T> persistentClass) {
		T bean = null;
		try {
			bean = persistentClass.newInstance();
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				Field field = null;
				// 项目中字段与数据库映射规则为cityName--city_name,在反射中取出来的为带"_"的，所以进行处理
				String key = entry.getKey();
				int temp = key.indexOf("_");
				if (temp > 0) {
					String first = key.substring(0, temp);
					String sec = key.substring(temp + 1, temp + 2)
							.toUpperCase();
					String third = key.substring(temp + 2, key.length());
					StringBuffer sb = new StringBuffer();
					sb.append(first).append(sec).append(third);
					key = sb.toString();
				}
				try {
					field = persistentClass.getDeclaredField(key);
				} catch (NoSuchFieldException e) {
					// 到该类的父类中去找
					try {
						field = persistentClass.getSuperclass()
								.getDeclaredField(key);
					} catch (NoSuchFieldException e1) {
						// 到该类的父类的父类中去找
						try {
							field = persistentClass.getSuperclass()
									.getSuperclass().getDeclaredField(key);
						} catch (NoSuchFieldException e2) {
							// 目前项目中的pojo的子父类关系最多为三级，所以超出3级后就直接抛出异常了
							e2.printStackTrace();
						}
					}
				}
				field.setAccessible(true);
				field.set(bean, entry.getValue());
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return bean;
	}

	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	/**
	 * 构造方法，初始化一个连接
	 */
	public JDBCDao() {
		Connection conn = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			System.out.println("找不到驱动程序");
		}
		try {
			String url = "jdbc:mysql://192.168.0.200:3306/ninegrid_game?user=ppc&password=123456";
			conn = (Connection) DriverManager.getConnection(url);
			statement = conn.createStatement();
			// String url = "jdbc:mysql://localhost:3306/AddressBook";
			// String user = "ZhuJun";
			// String password = "123456";
			// Connection conn = DriverManager.getConnection(url, user,
			// password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		this.connection = conn;
	}

	public Statement getStatement() {
		return statement;
	}

	public void setStatement(Statement statement) {
		this.statement = statement;
	}

	public ResultSet getResultSet() {
		return resultSet;
	}

	public void setResultSet(ResultSet resultSet) {
		this.resultSet = resultSet;
	}

}
